package com.yonyou.crm.cum.customer.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yonyou.crm.base.doc.service.BaseDocDetailBizServiceImpl;
import com.yonyou.crm.base.industry.service.IndustryBizServiceImpl;
import com.yonyou.crm.common.biz.service.BaseBizServiceImpl;
import com.yonyou.crm.common.enumeration.service.EnumBizServiceImpl;
import com.yonyou.crm.common.field.handler.FieldRelationHandler;
import com.yonyou.crm.common.field.relation.EnumFieldRelation;
import com.yonyou.crm.common.field.relation.FieldRelation;
import com.yonyou.crm.common.field.relation.RefFieldRelation;
import com.yonyou.crm.common.login.context.LoginContextConstant;
import com.yonyou.crm.common.model.util.IConverter;
import com.yonyou.crm.common.model.util.ModelUtil;
import com.yonyou.crm.common.page.entity.Page;
import com.yonyou.crm.cum.customer.entity.CustomerDO;
import com.yonyou.crm.cum.customer.entity.CustomerSalesDO;
import com.yonyou.crm.cum.customer.entity.CustomerSalesVO;
import com.yonyou.crm.cum.customer.entity.CustomerVO;
import com.yonyou.crm.sys.dataright.entity.RightActionEnum;
import com.yonyou.crm.sys.dataright.entity.RightObjectEnum;
import com.yonyou.crm.sys.dataright.service.RightServiceImpl;
import com.yonyou.crm.sys.org.entity.SysOrgDO;
import com.yonyou.crm.sys.region.service.RegionsBizServiceImpl;
import com.yonyou.crm.sys.role.entity.RoleVO;
import com.yonyou.crm.sys.role.service.RoleBizServiceImpl;
import com.yonyou.crm.sys.user.entity.UserVO;
import com.yonyou.crm.sys.user.service.UserBizServiceImpl;
import com.yonyou.iuap.context.InvocationInfoProxy;

@Service
public class CustomerChartBizServiceImpl extends BaseBizServiceImpl<CustomerVO> {
	
	@Autowired
	private RoleBizServiceImpl roleService;
	
	@Autowired
	private UserBizServiceImpl userService;
	
	@Autowired
	private CustomerBizServiceImpl customerService;
	
	@Autowired
	private RegionsBizServiceImpl regionService;
	
	@Autowired
    private RightServiceImpl rightService;
	
	@Autowired
    private CustomerSalesBizServiceImpl saleService;
	
	@Autowired
    private BaseDocDetailBizServiceImpl baseDocDetailBizService;
	
    @Autowired
    private IndustryBizServiceImpl IndustryBizService;
    
    @Autowired
    private EnumBizServiceImpl enumService;
	
	/**
	 * 客户分布左上角数据
	 * @param deptId
	 * @param userId
	 * @return
	 */
	public Object getOwnerDatas(Long deptId, Long userId) {
		
		Long curUserId = Long.parseLong(InvocationInfoProxy.getParameter("id"));// 用户id
		
		List<RoleVO> roleList = roleService.getUserRole(curUserId);
		int roleId = roleList.get(0).getType();// 获取角色类型
		Map<String,Object> result = new HashMap<String, Object>();

		if (roleId == 83 || userId!=null) {// 角色为销售员、（或）公司内勤查询某个业务员负责客户、（或）销售经理查询某个业务员负责客户
			result = handleUser(userId);
		} else if (roleId == 84 || deptId!=null) {// 角色为销售经理、（或）公司内勤查询某个部门负责客户
			result = handleDept(deptId);
		} else if (roleId == 85) {// 角色为公司内勤
			result = handleOrg();
		}
		return result;
	}
	
	/**
	 * 客户分布左下角客户数据
	 * @param page
	 * @param paramMap
	 * @return
	 */
	public Page<CustomerVO> getCustomers(Page<CustomerVO> page, Map<String, Object> paramMap) {
		Map<String, Object> idParam = new HashMap<String, Object>();
		idParam.put("tenantId", InvocationInfoProxy.getTenantid());
		idParam.put("orgId", InvocationInfoProxy.getParameter("orgid"));// 所属公司
		idParam.put("enablestate", 1);
		
		Long deptId = "".equals(paramMap.get("deptId"))?null:Long.parseLong(String.valueOf(paramMap.get("deptId")));
		Long userId = "".equals(paramMap.get("userId"))?null:Long.parseLong(String.valueOf(paramMap.get("userId")));
		if(userId != null||deptId != null){
			if(userId != null){
				idParam.put("userId", userId);
			}else if(deptId != null){
				idParam.put("deptId", deptId);
			}
		}
		
		Page<CustomerDO> pageList = dao.pageSelect(CustomerDO.class, page, "pageCustomer4Chart", "pageCountCustomer4Chart", idParam);
		Page<CustomerVO> result = ModelUtil.copyPageModel(pageList, CustomerVO.class, new IConverter<CustomerDO, CustomerVO>() {
            @Override
            public void convert(CustomerDO origObj, CustomerVO destObj) {
                List<CustomerSalesVO> saleVos = ModelUtil.copyModelList(origObj.getSalesDOs(), CustomerSalesVO.class);
                destObj.setSalesVOs(saleService.transCustomerSale(saleVos));
            }
        });

        transCustomer(result.getData());
		return result;
	}
	
	/**
	 * 客户状态右侧图表数据
	 * @param deptId
	 * @param userId
	 * @return
	 */
	public List<Map<String, Object>> getRatio(Long deptId, Long userId){
		Long curUserId = Long.parseLong(InvocationInfoProxy.getParameter("id"));// 用户id
		
		List<RoleVO> roleList = roleService.getUserRole(curUserId);
		int roleId = roleList.get(0).getType();// 获取角色类型
		Map<String, Object> custPara = new HashMap<String, Object>();
		if (roleId == 83 || userId!=null) {// 角色为销售员、公司内勤查询某个业务员、销售经理查询某个业务员
			if(userId == null){
				userId = curUserId;
			}
			custPara.put("userId", userId);
		} else if (roleId == 84 || deptId!=null) {// 角色为销售经理、公司内勤查询某个部门
			if(deptId == null){
				deptId = Long.parseLong(InvocationInfoProxy.getParameter("deptid"));// 部门id
			}
			custPara.put("deptId", deptId);
		} else if (roleId == 85) {// 角色为公司内勤
			Long orgId = Long.parseLong(InvocationInfoProxy.getParameter("orgid"));// 公司id
			custPara.put("orgId", orgId);
		}
		List<Map<String, Object>> ratio = dao.selectList(CustomerSalesDO.class, "countRatio4Chart", custPara);
		return ratio;
	}
	
	private Map<String, Object> handleUser(Long userId){
		if(userId==null){
			userId = Long.parseLong(InvocationInfoProxy.getParameter("id"));
		}
		UserVO user = userService.getDetail(userId);
		Long id = user.getId();
		Map<String, Object> custPara = new HashMap<String, Object>();
		custPara.put("userIds", new Long[]{id});
		List<Map<String, Object>> sales = dao.selectList(CustomerSalesDO.class, "countByUser4Chart", custPara);
		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		Map<String,Object> userMap = new HashMap<String,Object>();
		userMap.put("id", id);
		userMap.put("name", user.getName());
		list.add(userMap);
		Map<String, Object> userNum = handleDatas4User(list, sales);
		userNum.put("flag", "user");
		return userNum;
	}
	
	private Map<String,Object> handleDept(Long deptId){
		if(deptId==null){
			deptId = Long.parseLong(InvocationInfoProxy.getParameter("deptid"));
		}
		List<Map<String, Object>> users = userService.getUserByDeptId(deptId, "");
		List<Object> userIds = new ArrayList<Object>();
		for(Map<String, Object> user:users){
			userIds.add(user.get("id"));
		}
		//兼容部门下没人的场景
		userIds.add(-1L);
		Map<String, Object> custPara = new HashMap<String, Object>();
		custPara.put("userIds", userIds);
		List<Map<String, Object>> sales = dao.selectList(CustomerSalesDO.class, "countByUser4Chart", custPara);
		Map<String, Object> userNum = handleDatas4User(users, sales);
		userNum.put("flag", "user");
		return userNum;
	}
	
	private Map<String,Object> handleOrg(){
		Map<String, Object> deptPara = new HashMap<String, Object>();
		deptPara.put("id", InvocationInfoProxy.getParameter("orgid"));
		List<Map<String, Object>> depts = dao.selectList(SysOrgDO.class, "findDeptTreeChildren", deptPara);
		Map<String, Object> custPara = new HashMap<String, Object>();
		custPara.put("orgId", InvocationInfoProxy.getParameter("orgid"));
		List<Map<String, Object>> sales = dao.selectList(CustomerSalesDO.class, "countByDept4Chart", custPara);
		Map<String,Object> result = handleDatas4Dept(depts, sales);
		result.put("flag", "dept");
		return result;
	}
	
	private Map<String, Object> handleDatas4Dept(List<Map<String, Object>> depts, List<Map<String, Object>> sales){
		List<Object> regionIds = new ArrayList<Object>();
		for(Map<String, Object> temp:sales){
			regionIds.add(temp.get("province"));
			regionIds.add(temp.get("city"));
		}
		List<Map<String, Object>> regions = (List<Map<String, Object>>) regionService.selectFieldsByIds(regionIds.toArray(new Object[0]));
		Map<String, Object> deptNum = new HashMap<String, Object>();
		Long total = 0L;
		for(Map<String, Object> dept:depts){
			String id = String.valueOf(dept.get("id"));
			String name = String.valueOf(dept.get("name"));
			Map<String, Object> u = (Map<String, Object>) deptNum.get(id);
			if(u==null){
				u = new HashMap<String, Object>();
				u.put("id", id);
				u.put("name", name);
				u.put("num", 0);
				deptNum.put(id, u);
			}
			for(Map<String, Object> temp:sales){
				String deptid = String.valueOf(temp.get("owner_dept_id"));
				if(!id.equals(deptid)){
					continue;
				}
				Long num = (Long) temp.get("num");
				u.put("num", Long.valueOf(String.valueOf(u.get("num")))+num);
				Map<String, Object> pn = (Map<String, Object>) u.get("province");
				if(pn==null){
					pn = new HashMap<String, Object>();
					u.put("province", pn);
				}
				String pid = null==temp.get("province")?"zero":String.valueOf(temp.get("province"));
				Map<String, Object> p = (Map<String, Object>) pn.get(pid);
				if(p==null){
					p = new HashMap<String, Object>();
					p.put("id", pid);
					Object pname = "";
					for(Map<String, Object> reg:regions){
						if(pid.equals(String.valueOf(reg.get("id")))){
							pname = reg.get("name");
						}
					}
					p.put("name", pname);
					p.put("num", 0);
					pn.put(pid, p);
				}
				p.put("num", Long.valueOf(String.valueOf(p.get("num")))+num);
				Map<String, Object> cn = (Map<String, Object>) p.get("city");
				if(cn==null){
					cn = new HashMap<String, Object>();
					p.put("city", cn);
				}
				String cid = null==temp.get("city")?"zero":String.valueOf(temp.get("city"));
				Map<String, Object> c = (Map<String, Object>) cn.get(cid);
				if(c==null){
					c = new HashMap<String, Object>();
					c.put("id", cid);
					Object cname = "";
					for(Map<String, Object> reg:regions){
						if(cid.equals(String.valueOf(reg.get("id")))){
							cname = reg.get("name");
						}
					}
					c.put("name", cname);
					c.put("num", 0);
					cn.put(cid, c);
				}
				c.put("num", Long.valueOf(String.valueOf(c.get("num")))+num);
				
				total = total + num;
			}
		}
		
		deptNum.put("total", total);
		
		List<Object> list= new ArrayList<Object>();
		total = (Long) deptNum.get("total");
		deptNum.remove("total");
		Collection<Object> deptnums = deptNum.values();
		list.addAll(deptnums);
		
		Map result = new HashMap();
		result.put("list", list);
		result.put("total", total);
		
		for(Object obj:deptnums){
			Map objMap = (Map)obj;
			Object province = objMap.get("province");
			if(province==null){
				continue;
			}
			Map provinceMap = (Map)province;
			objMap.remove("province");
			Collection<Object> provinces = provinceMap.values();
			objMap.put("province", provinces);
			for(Object p:provinces){
				Map pMap = (Map)p;
				Object city = pMap.get("city");
				Map cityMap = (Map)city;
				pMap.remove("city");
				Collection<Object> citys = cityMap.values();
				pMap.put("city", citys);
			}
		}
		
		return result;
	}
	
	private Map<String, Object> handleDatas4User(List<Map<String, Object>> users, List<Map<String, Object>> sales){
		List<Object> regionIds = new ArrayList<Object>();
		for(Map<String, Object> temp:sales){
			regionIds.add(temp.get("province"));
			regionIds.add(temp.get("city"));
		}
		regionIds.add("");						//预防数据中都没有省市的情况
		List<Map<String, Object>> regions = (List<Map<String, Object>>) regionService.selectFieldsByIds(regionIds.toArray(new Object[0]));
		Map<String, Object> userNum = new HashMap<String, Object>();
		Long total = 0L;	
		for(Map<String, Object> user:users){
			String id = String.valueOf(user.get("id"));
			String name = String.valueOf(user.get("name"));
			Map<String, Object> u = (Map<String, Object>) userNum.get(id);
			if(u==null){
				u = new HashMap<String, Object>();
				u.put("id", id);
				u.put("name", name);
				u.put("num", 0);
				userNum.put(id, u);
			}
			for(Map<String, Object> temp:sales){
				String userid = String.valueOf(temp.get("owner_user_id"));
				if(!id.equals(userid)){
					continue;
				}	
				Long num = (Long) temp.get("num");
				u.put("num", Long.valueOf(String.valueOf(u.get("num")))+num);
				Map<String, Object> pn = (Map<String, Object>) u.get("province");
				if(pn==null){
					pn = new HashMap<String, Object>();
					u.put("province", pn);
				}
				String pid = null==temp.get("province")?"zero":String.valueOf(temp.get("province"));
				Map<String, Object> p = (Map<String, Object>) pn.get(pid);
				if(p==null){
					p = new HashMap<String, Object>();
					p.put("id", pid);
					Object pname = "";
					for(Map<String, Object> reg:regions){
						if(pid.equals(String.valueOf(reg.get("id")))){
							pname = reg.get("name");
						}
					}
					p.put("name", pname);
					p.put("num", 0);
					pn.put(pid, p);
				}
				p.put("num", Long.valueOf(String.valueOf(p.get("num")))+num);
				Map<String, Object> cn = (Map<String, Object>) p.get("city");
				if(cn==null){
					cn = new HashMap<String, Object>();
					p.put("city", cn);
				}
				String cid = null==temp.get("city")?"zero":String.valueOf(temp.get("city"));
				Map<String, Object> c = (Map<String, Object>) cn.get(cid);
				if(c==null){
					c = new HashMap<String, Object>();
					c.put("id", cid);
					Object cname = "";
					for(Map<String, Object> reg:regions){
						if(cid.equals(String.valueOf(reg.get("id")))){
							cname = reg.get("name");
						}
					}
					c.put("name", cname);
					c.put("num", 0);
					cn.put(cid, c);
				}
				c.put("num", Long.valueOf(String.valueOf(c.get("num")))+num);
				
				total = total + num;
			}
		}
		
		userNum.put("total", total);
		
		List<Object> list= new ArrayList<Object>();
		total = (Long) userNum.get("total");
		userNum.remove("total");
		Collection<Object> usernums = userNum.values();
		list.addAll(usernums);
		
		Map result = new HashMap();
		result.put("list", list);
		result.put("total", total);
		
		for(Object obj:usernums){
			Map objMap = (Map)obj;
			Object province = objMap.get("province");
			if(province==null){
				continue;
			}
			Map provinceMap = (Map)province;
			objMap.remove("province");
			Collection<Object> provinces = provinceMap.values();
			objMap.put("province", provinces);
			for(Object p:provinces){
				Map pMap = (Map)p;
				Object city = pMap.get("city");
				Map cityMap = (Map)city;
				pMap.remove("city");
				Collection<Object> citys = cityMap.values();
				pMap.put("city", citys);
			}
		}
		
		return result;
	}
	
	private List<CustomerVO> transCustomer(List<CustomerVO> customerList) {
        List<FieldRelation<CustomerVO>> relations = new ArrayList<FieldRelation<CustomerVO>>();
        //基础档案：1-客户类型、2-渠道类型、5-客户等级、6-客户状态
        relations.add(new RefFieldRelation<CustomerVO>(CustomerVO.class, "type", new String[]{"typeName"}, baseDocDetailBizService, "selectFieldsByIds"));
        relations.add(new RefFieldRelation<CustomerVO>(CustomerVO.class, "cannelType", new String[]{"cannelTypeName"}, baseDocDetailBizService, "selectFieldsByIds"));
        relations.add(new RefFieldRelation<CustomerVO>(CustomerVO.class, "level", new String[]{"levelName"}, baseDocDetailBizService, "selectFieldsByIds"));
        relations.add(new RefFieldRelation<CustomerVO>(CustomerVO.class, "state", new String[]{"stateName"}, baseDocDetailBizService, "selectFieldsByIds"));
        //行业
        relations.add(new RefFieldRelation<CustomerVO>(CustomerVO.class, "industry", new String[]{"industryName"}, IndustryBizService, "selectFieldsByIds"));
        //上级客户
        relations.add(new RefFieldRelation<CustomerVO>(CustomerVO.class, "parentId", new String[]{"parentName"}, this, "selectFieldsByIds"));
        //省、市、区
        relations.add(new RefFieldRelation<CustomerVO>(CustomerVO.class, "province", new String[]{"provinceName"}, regionService, "selectFieldsByIds"));
        relations.add(new RefFieldRelation<CustomerVO>(CustomerVO.class, "city", new String[]{"cityName"}, regionService, "selectFieldsByIds"));
        relations.add(new RefFieldRelation<CustomerVO>(CustomerVO.class, "district", new String[]{"districtName"}, regionService, "selectFieldsByIds"));
        //启用标识
        relations.add(new EnumFieldRelation<CustomerVO>(CustomerVO.class, "enableState", "enableStateName", enumService, "enable_state"));
        //集团客户标识
        relations.add(new EnumFieldRelation<CustomerVO>(CustomerVO.class, "isGroup", "isGroupName", enumService, "cum_sign"));
        new FieldRelationHandler<CustomerVO>().handler(customerList, relations);
        return customerList;
    }
}
